﻿#include"ecomsys.h"
#include <memory>
#include<algorithm>
//#include <sstream>



string eComSys::centerText(const string& text) const {
		int padding = max(0ll, width - 2 - static_cast<int>(text.length())); // 确保 padding ≥ 0
		int left = padding / 2;
		int right = padding - left;
		return string(10, ' ') + text + string(right, ' ');
	}

	// 生成边框线
string eComSys::createDivider() const {
		return string(width, divider[0]);
	}


eComSys::eComSys(int w, std::string div, std::string p)
	: userManager("user.json"), productManager("product.json"), orderManager("order.json"),width(w) ,divider(div),prompt(p){
	userManager.readInAlluser();
	productManager.readInAllProducts();
	orderManager.loadAllOrders();
}


eComSys::~eComSys() {
	//释放socket资源
	closesocket(listenSocket);
	WSACleanup();
}





//暂时定为监听广播地址，8080端口
bool eComSys::initSocket() {
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
		std::cerr << "WSAStartup失败\n";
		return false;
	}

	listenSocket = socket(AF_INET, SOCK_STREAM, 0);
	if (listenSocket == INVALID_SOCKET) {
		WSACleanup();
		return false;
	}

	serverAddr.sin_family = AF_INET;
	serverAddr.sin_port = htons(8080);
	serverAddr.sin_addr.s_addr = INADDR_ANY;

	if (::bind(listenSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
		closesocket(listenSocket);
		WSACleanup();
		return false;
	}

	if (listen(listenSocket, SOMAXCONN) == SOCKET_ERROR) {
		closesocket(listenSocket);
		WSACleanup();
		return false;
	}

	return true;
}

void eComSys::runServer() {
	if (!initSocket()) {
		std::cerr << "服务器启动失败\n";
		return;
	}

	std::cout << "服务器运行中...\n";
	while (true) {
		sockaddr_in clientAddr;
		int addrLen = sizeof(clientAddr);
		SOCKET clientSocket = accept(listenSocket, (sockaddr*)&clientAddr, &addrLen);
		if (clientSocket == INVALID_SOCKET) {
			continue;
		}
		//cout << "来喽" << endl;
		std::thread([this, clientSocket]() {
			this->MainMenu(clientSocket);
			}).detach();
	}
}




	// 添加菜单项
void eComSys:: addMainItem(const string& item) {
		mainitems.push_back(item);
	}

//=================================================================================
//商品菜单功能实现
//=================================================================================
//展示所有商品
void eComSys::displayProducts(SOCKET clientSocket) const {
	auto sendData = [clientSocket](const string& data) {
		if (send(clientSocket, data.c_str(), data.size(), 0) == SOCKET_ERROR) {
			return;
		}
		};

	try {
		ostringstream oss;

		// 空数据提示
		if (products.empty()) {
			oss << "\n当前没有商品可展示。\n";
			sendData(oss.str());
			return;
		}

		// 构建表头
		oss << "\n当前所有商品信息：\n"
			<< left
			<< setw(15) << "商户"
			<< setw(25) << "商品ID"
			<< setw(40) << "描述"
			<< setw(10) << "原价"
			<<setw(10)<<"折扣"
			<<setw(10)<<"税率"
			<< setw(10) << "现价"
			<< setw(6) << "库存\n"
			<< string(120, '-') << "\n";

		// 格式化商品数据
		for (const auto& [key, prod] : products) {
			const auto& [owner, id] = key;
			oss << left
				<< setw(15) << owner.substr(0, 14)  // 限制商户名称长度
				<< setw(25) << (" " + id + " ")     // 增加ID可视性
				<< setw(40) << prod->getDescription().substr(0, 39)  // 限制描述长度
				<< fixed << setprecision(2)
				<< setw(10) << prod->getOriginalPrice()
				<< setw(10) << prod->getDiscountRate()
				<< setw(10) << prod->getTaxRate()
				<< setw(10) << prod->getPrice()
				<< setw(6) << prod->getStock() << "\n";
		}

		// 发送完整数据
		sendData(oss.str());
	}
	catch (const exception& e) {
		string errMsg = "\n系统错误: " + string(e.what()) + "\n";
		send(clientSocket, errMsg.c_str(), errMsg.size(), 0);
	}
}

//从所有商品里搜索
void eComSys::searchProducts(SOCKET clientSocket) const {
	auto sendData = [clientSocket](const string& data) {
		if (send(clientSocket, data.c_str(), data.size(), 0) == SOCKET_ERROR) {
			return;
		}
		};

	auto receiveInput = [clientSocket,sendData](const string& prompt, string& output) -> bool {
		sendData(prompt);
		char buffer[256] = { 0 };
		int bytesReceived = recv(clientSocket, buffer, sizeof(buffer) - 1, 0);
		if (bytesReceived <= 0) return false;
		output = string(buffer, bytesReceived);
		return true;
		};

	try {
		// 获取搜索关键词
		string keyword;
		if (!receiveInput("\n输入搜索关键词（商品名称、商户、描述；单空格跳过）: ", keyword)) {
			return;
		}

		// 获取价格范围
		string priceRange;
		double minPrice = 0, maxPrice = 0;
		do {
			if (!receiveInput("输入价格范围（格式：最小 最大）；空格跳过: ", priceRange)) {
				return;
			}

			stringstream ss(priceRange);
			if (priceRange != " ") {
				if (!(ss >> minPrice >> maxPrice)) {
					sendData("错误：请输入两个数字（例：100 500）\n");
					continue;
				}

				if (minPrice < 0 || maxPrice < minPrice) {
					sendData("错误：价格范围无效（最小价格需<=最大价格）\n");
				}
			}
			else {
				break;
			}
		} while (true);

		// 构建搜索结果
		ostringstream oss;
		oss << "\n搜索结果：\n"
			<< left
			<< setw(15) << "商户"
			<< setw(25) << "商品ID"
			<< setw(40) << "描述"
			<< setw(10) << "现价"
			<< setw(6) << "库存\n"
			<< string(95, '-') << "\n";

		bool hasResult = false;
		for (const auto& [key, prod] : products) {
			const auto& [owner, id] = key;

			// 匹配逻辑
			bool nameMatch =( keyword==" ") ||
				(id.find(keyword) != string::npos ||
					prod->getDescription().find(keyword) != string::npos ||
					owner.find(keyword) != string::npos);

			bool priceMatch = (prod->getPrice() >= minPrice) &&
				(prod->getPrice() <= maxPrice)|| priceRange == " ";

			if (nameMatch && priceMatch) {
				hasResult = true;
				oss << left
					<< setw(15) << owner.substr(0, 14)
					<< setw(25) << (" " + id + " ")
					<< setw(40) << prod->getDescription().substr(0, 39)
					<< fixed << setprecision(2)
					<< setw(10) << prod->getPrice()
					<< setw(6) << prod->getStock() << "\n";
			}
		}

		// 处理无结果情况
		if (!hasResult) {
			oss << "\n未找到匹配商品\n";
		}

		// 发送最终结果
		sendData(oss.str());
	}
	catch (const exception& e) {
		string errMsg = "\n搜索错误: " + string(e.what()) + "\n";
		send(clientSocket, errMsg.c_str(), errMsg.size(), 0);
	}
}

void eComSys::addProduct(SOCKET clientSocket) {
	auto sendPrompt = [clientSocket](const string& msg) {
		if (send(clientSocket, msg.c_str(), msg.size(), 0) == SOCKET_ERROR) {
			throw std::runtime_error("发送商品添加数据失败");
		}
		};

	auto receiveInput = [clientSocket]() -> string {
		char buffer[256] = { 0 };
		int bytes = recv(clientSocket, buffer, sizeof(buffer) - 1, 0);
		if (bytes <= 0) throw std::runtime_error("连接中断");
		return string(buffer, bytes);
		};

	// 数值验证 lambda（支持整数和浮点数）
	auto validateNumber = [&](const string& input, double min, double max, double& outValue) -> bool {
		try {
			float value = stof(input);
			if (value >= min && value <= max) {
				outValue = value;
				return true;
			}
		}
		catch (...) {
			// 捕获转换异常
			return false;
		}
		// 捕获范围异常
		return false;
		};

	try {
		// 验证登录状态
		if (currentUserID.empty()) {
			sendPrompt("错误：请先登录\n");
			return;
		}

		// 商品ID验证
		string id;
		while (true) {
			sendPrompt("\n=== 添加新商品 ===\n商品ID（唯一标识，输入q退出）: ");
			id = receiveInput();

			if (id == "q") return;

			ProductKey key = { currentUserID, id };
			if (products.count(key)) {
				sendPrompt("⚠️ 该ID已存在，请重新输入\n");
			}
			else {
				break;
			}
		}

		// 商品描述
		sendPrompt("商品描述（最多100字符）: ");
		string desc = receiveInput().substr(0, 100);

		// 价格输入
		double price;
		while (true) {
			sendPrompt("商品原价（0.01-1000000）: ");
			string input = receiveInput();
			if (validateNumber(input, 0.01, 1000000.0, price)) break;
			sendPrompt("输入无效，请重新输入\n");
		}

		// 库存输入（需要整数）
		int stock;
		while (true) {
			sendPrompt("库存数量（0-9999）: ");
			string input = receiveInput();
			double value;
			if (validateNumber(input, 0, 9999.0, value)) {
				if (value == static_cast<int>(value)) {
					stock = static_cast<int>(value);
					break;
				}
			}
			sendPrompt("请输入有效整数\n");
		}

		// 商品类型选择
		int type;
		while (true) {
			string typeMenu =
				"选择商品类型:\n"
				"1. 图书（折扣率）\n"
				"2. 电子产品（折扣率+税率）\n"
				"3. 服装（折扣率）\n"
				"请选择（1-3）: ";
			sendPrompt(typeMenu);

			string input = receiveInput();
			double value;
			if (validateNumber(input, 1, 3, value) &&
				value == static_cast<int>(value)) {
				type = static_cast<int>(value);
				break;
			}
			sendPrompt("请输入1-3的整数\n");
		}

		// 创建商品对象
		ProductKey key = { currentUserID, id };
		switch (type) {
		case 1: { // 图书
			double discount;
			while (true) {
				sendPrompt("折扣率（0-1）: ");
				string input = receiveInput();
				if (validateNumber(input, 0.0, 1.0, discount)) break;
				sendPrompt("输入无效，请重新输入\n");
			}
			products[key] = make_unique<Book>(
				currentUserID, id, desc, price, stock, discount);
			break;
		}
		case 2: { // 电子产品
			double discount, tax;
			while (true) {
				sendPrompt("折扣率（0-1）: ");
				string input = receiveInput();
				if (validateNumber(input, 0.0, 1.0, discount)) break;
				sendPrompt("输入无效，请重新输入\n");
			}
			while (true) {
				sendPrompt("税率（0-1）: ");
				string input = receiveInput();
				if (validateNumber(input, 0.0, 1.0, tax)) break;
				sendPrompt("输入无效，请重新输入\n");
			}
			products[key] = make_unique<Electronics>(
				currentUserID, id, desc, price, stock, discount, tax);
			break;
		}
		case 3: { // 服装
			double discount;
			while (true) {
				sendPrompt("折扣率（0-1）: ");
				string input = receiveInput();
				if (validateNumber(input, 0.0, 1.0, discount)) break;
				sendPrompt("输入无效，请重新输入\n");
			}
			products[key] = make_unique<Clothing>(
				currentUserID, id, desc, price, stock, discount);
			break;
		}
		}

		// 保存数据
		productManager.storeInProduct(*products[key]);
		sendPrompt("✅ 商品添加成功！\n");
	}
	catch (const exception& e) {
		string msg = "添加商品错误: " + string(e.what()) + "\n";
		send(clientSocket, msg.c_str(), msg.size(), 0);
		closesocket(clientSocket);
	}
}



// 实现商品管理功能
void eComSys::manageProducts(SOCKET clientSocket) {
	auto sendPrompt = [clientSocket](const string& msg) {
		if (send(clientSocket, msg.c_str(), msg.size(), 0) == SOCKET_ERROR) {
			throw std::runtime_error("发送商品管理数据失败");
		}
		};

	auto receiveChoice = [clientSocket]() -> int {
		char buffer[16] = { 0 };
		int bytes = recv(clientSocket, buffer, sizeof(buffer) - 1, 0);
		if (bytes <= 0) return -1;
		return atoi(buffer);
		};

	try {
		// 验证登录状态
		if (currentUserID.empty()) {
			sendPrompt("错误：请先登录！\n");
			return;
		}

		// 收集当前商户商品
		vector<ProductKey> myProducts;
		for (const auto& [key, _] : products) {
			if (key.first == currentUserID) {
				myProducts.push_back(key);
			}
		}

		// 无商品处理
		if (myProducts.empty()) {
			sendPrompt("您尚未添加任何商品\n");
			return;
		}

		// 构建商品列表
		ostringstream oss;
		oss << "\n=== 您的商品列表 ===\n"
			<< left
			<< setw(4) << "序号"
			<< setw(25) << "商品ID"
			<< setw(40) << "描述"
			<< setw(10) << "现价"
			<< setw(6) << "库存\n"
			<< string(85, '-') << "\n";

		int index = 1;
		for (const auto& key : myProducts) {
			auto& prod = products[key];
			oss << left
				<< setw(4) << index++
				<< setw(25) << (" " + key.second + " ")
				<< setw(40) << prod->getDescription().substr(0, 39)
				<< fixed << setprecision(2)
				<< setw(10) << prod->getPrice()
				<< setw(6) << prod->getStock() << "\n";
		}
		oss << "\n输入要修改的商品序号（0返回）: ";
		sendPrompt(oss.str());

		// 获取用户选择
		int choice = receiveChoice();
		if (choice == -1) throw std::runtime_error("连接中断");
		if (choice < 0 || choice > myProducts.size()) {
			sendPrompt("错误：无效的商品序号\n");
			return;
		}
		if (choice == 0) return;

		// 获取选定商品
		ProductKey selectedKey = myProducts[choice - 1];
		modifyProduct(products[selectedKey].get(), clientSocket); // 修改后的函数需要支持socket
	}
	catch (const exception& e) {
		string msg = "商品管理错误: " + string(e.what()) + "\n";
		send(clientSocket, msg.c_str(), msg.size(), 0);
	}
}




// 实现商品修改功能
void eComSys::modifyProduct(product* prod, SOCKET clientSocket) {
	auto sendPrompt = [clientSocket](const string& msg) {
		if (send(clientSocket, msg.c_str(), msg.size(), 0) == SOCKET_ERROR) {
			throw std::runtime_error("修改商品通信失败");
		}
		};

	auto receiveInput = [clientSocket]() -> string {
		char buffer[256] = { 0 };
		int bytes = recv(clientSocket, buffer, sizeof(buffer) - 1, 0);
		if (bytes <= 0) throw std::runtime_error("连接中断");
		return string(buffer);
		};

	// 修改后的验证函数（返回验证结果+输出参数）
	auto validateNumber = [&](const std::string& input,  double min, double max, double& outValue) -> bool {
		try {
			float value = std::stof(input);  // 修复：添加 stof 转换
			if (value >= min && value <= max) {
				outValue = value;
				return true;
			}
		}
		catch (...) {
			return false;
		}
		return false;
		};

	try {
		// 显示修改菜单（与原实现相同）
		ostringstream oss;
		oss << "\n当前商品信息：\n"
			<< "1. 描述: " << prod->getDescription() << "\n"
			<< "2. 原价: " << fixed << setprecision(2) << prod->getOriginalPrice() << "\n"
			<< "3. 库存: " << prod->getStock() << "\n";

		// ... 类型特有信息显示（保持原样）
		oss << "请输入要修改的选项编号（0提交修改）: ";
		sendPrompt(oss.str());

		// 修改循环
		while (true) {
			string choiceStr = receiveInput();
			int choice = stoi(choiceStr);

			if (choice == 0) break;

			switch (choice) {
			case 1: { // 描述修改
				sendPrompt("请输入新描述（最多40字符）: ");
				string desc = receiveInput();
				prod->setDescription(desc.substr(0, 40));
				break;
			}

			case 2: { // 原价修改
				auto getValue = [&]() -> double {
					double value;
					while (true) {
						sendPrompt("请输入新原价（0-1000000）: ");
						string input = receiveInput();
						if (validateNumber(input, 0.0, 1000000.0, value)) {
							return value;
						}
						sendPrompt("输入无效，请重新输入: ");
					}
					};
				prod->setOriginalPrice(getValue());
				break;
			}

			case 3: { // 库存修改
				auto getValue = [&]() -> int {
					double value;
					while (true) {
						sendPrompt("请输入新库存（0-9999）: ");
						string input = receiveInput();
						if (validateNumber(input, 0.0, 9999.0, value)) {
							return value;
						}
						sendPrompt("输入无效，请重新输入: ");
					}
					};
				prod->setStock(getValue());
				break;
			}

			case 4: { // 折扣率修改
				auto handleDiscount = [&](auto item) {
					double value;
					while (true) {
						sendPrompt("请输入新折扣率（0.0-1.0）: ");
						string input = receiveInput();
						if (validateNumber(input, 0.0, 1.0, value)) {
							item->setDiscountRate(value);
							break;
						}
						sendPrompt("输入无效，请重新输入: ");
					}
					};

				if (auto book = dynamic_cast<Book*>(prod)) {
					handleDiscount(book);
				}
				else if (auto elec = dynamic_cast<Electronics*>(prod)) {
					handleDiscount(elec);
				}
				else if (auto cloth = dynamic_cast<Clothing*>(prod)) {
					handleDiscount(cloth);
				}
				break;
			}

			case 5: { // 税率修改（仅电子产品）
				if (auto elec = dynamic_cast<Electronics*>(prod)) {
					double value;
					while (true) {
						sendPrompt("请输入新税率（0.0-0.2）: ");
						string input = receiveInput();
						if (validateNumber(input, 0.0, 0.2, value)) {
							elec->setTaxRate(value);
							break;
						}
						sendPrompt("输入无效，请重新输入: ");
					}
				}
				break;
			}

			default:
				sendPrompt("无效选项，请重新选择\n");
			}
			sendPrompt("完成 ");
		}

		// 保存修改
		productManager.saveAllProducts();
		sendPrompt("✅ 商品信息已更新！\n");
	}
	catch (const exception& e) {
		string msg = "修改错误: " + string(e.what()) + "\n";
		send(clientSocket, msg.c_str(), msg.size(), 0);
		closesocket(clientSocket);
	}
}

//=================================================================================
// 用户菜单功能实现
//=================================================================================
//注册
void eComSys::signIn(SOCKET clientSocket) {
	// 辅助函数：接收客户端输入
	auto receiveInput = [&](const string& prompt, string& output) -> bool {
		// 发送提示信息（直接发送整个字符串）
		if (send(clientSocket, prompt.c_str(), prompt.size(), 0) == SOCKET_ERROR) {
			cerr << "发送提示失败，错误码: " << WSAGetLastError() << endl;
			return false;
		}

		// 接收客户端响应
		char buffer[256] = { 0 };
		int bytesReceived = recv(clientSocket, buffer, sizeof(buffer) - 1, 0); // 保留null终止符

		if (bytesReceived <= 0) {
			cerr << "连接已关闭或接收错误，错误码: " << WSAGetLastError() << endl;
			return false;
		}

		// 处理换行符（可选）
		if (buffer[bytesReceived - 1] == '\n') {
			buffer[bytesReceived - 1] = '\0';
			bytesReceived--;
		}

		output = string(buffer, bytesReceived);
		return true;
		};
	//以上匿名函数定义


	try {
		// 用户类型选择
		string userType;
		while (true) {
			const string menu =
				"\n=== 用户类型选择 ===\n"
				"1. 消费者\n"
				"2. 商家\n"
				"请输入选项(1-2): ";

			string choice;
			if (!receiveInput(menu, choice)) return;

			if (choice == "1" || choice == "2") {
				userType = (choice == "1") ? "consumer" : "seller";
				break;
			}

			const string err = "错误：无效选项，请输入1或2！\n";
			send(clientSocket, err.c_str(), err.size(), 0);
		}

		// 账号注册
		string id;
		while (true) {
			const string prompt = "\n请输入账号（4-12位字母数字）: ";
			if (!receiveInput(prompt, id)) return;

			// 格式验证
			if (id.length() < 4 || id.length() > 12) {
				const string err = "错误：账号长度需在4-12位之间！\n";
				send(clientSocket, err.c_str(), err.size(), 0);
				continue;
			}

			// 唯一性检查
			if (users.count(id)) {
				const string err = "错误：该账号已存在！\n";
				send(clientSocket, err.c_str(), err.size(), 0);
			}
			else {
				break;
			}
		}

		// 密码设置
		string psw, confirm;
		do {
			const string prompt = "\n请输入密码（6-18位，包含字母和数字）: ";
			if (!receiveInput(prompt, psw)) return;

			// 密码复杂度验证
			bool hasAlpha = any_of(psw.begin(), psw.end(), ::isalpha);
			bool hasDigit = any_of(psw.begin(), psw.end(), ::isdigit);

			if (psw.length() < 6 || psw.length() > 18) {
				const string err = "错误：密码长度需在6-18位之间！\n";
				send(clientSocket, err.c_str(), err.size(), 0);
				continue;
			}

			if (!(hasAlpha && hasDigit)) {
				const string err = "错误：密码必须包含字母和数字！\n";
				send(clientSocket, err.c_str(), err.size(), 0);
				continue;
			}

			// 确认密码
			const string confirmPrompt = "请再次输入密码确认: ";
			if (!receiveInput(confirmPrompt, confirm)) return;

			if (psw != confirm) {
				const string err = "错误：两次输入的密码不一致！\n";
				send(clientSocket, err.c_str(), err.size(), 0);
			}
		} while (psw != confirm);

		// 创建用户对象
		unique_ptr<user> newUser;
		if (userType == "seller") {
			newUser = make_unique<seller>(id, psw, userType);
		}
		else {
			newUser = make_unique<consumer>(id, psw, userType);
		}

		// 保存数据
		users[id] = move(newUser);
		userFileManager fd("user.json");
		fd.storeInuser(*users[id]);

		// 发送成功响应
		const string successMsg =
			"\n=== 注册成功 ===\n"
			"账号: " + id + "\n" +
			"类型: " + userType + "\n" +
			"==============================\n";
		send(clientSocket, successMsg.c_str(), successMsg.size(), 0);
	}
	catch (const exception& e) {
		const string errMsg = "\n系统错误: " + string(e.what()) + "\n";
		send(clientSocket, errMsg.c_str(), errMsg.size(), 0);
		closesocket(clientSocket);
	}
	catch (...) {
		const string errMsg = "\n发生未知错误！\n";
		send(clientSocket, errMsg.c_str(), errMsg.size(), 0);
		closesocket(clientSocket);
	}
}


void eComSys::displayAllAc(SOCKET clientSocket) const {
	// 构建表格内容的核心函数
	auto buildUserList = [](vector<const user*>& Users, const string& title) {
		ostringstream oss;
		const vector<int> colWidths = { 20, 15, 15, 15 };

		// 表头
		oss << "\n=== " << title << " ===\n"
			<< left
			<< setw(colWidths[0]) << "ID"
			<< setw(colWidths[1]) << "Password"
			<< setw(colWidths[2]) << "Balance"
			<< setw(colWidths[3]) << "Type";
		oss << "\n";
		// 数据行
		for (auto User : Users) {
			string info = User->userInfo();
			string id = User->getId();
			// 直接解析用户信息字段
			oss << left
				<< setw(colWidths[0]) << id                 // ID
				<< setw(colWidths[1]) << "******"                                 // 密码占位
				<< setw(colWidths[2]) << fixed << setprecision(2)                 // 金额格式
				<< User->getAccountMoney()                                   // 余额
				<< setw(colWidths[3]) << User->getUserType() << "\n";// 类型
		}
		return oss.str();
		};

	try {
		// 分类用户
		vector<const user*> sellers, consumers;
		for (const auto& [id, user] : users) {
			if (user->getUserType() == "seller") {
				sellers.push_back(user.get());
			}
			else {
				consumers.push_back(user.get());
			}
		}

		// 构建完整响应
		string response;
		response += buildUserList(sellers, "商户列表");
		response += buildUserList(consumers, "消费者列表");

		// 发送数据
		if (send(clientSocket, response.c_str(), response.size(), 0) == SOCKET_ERROR) {
			return;
		}
	}
	catch (const exception& e) {
		string errMsg = "\n系统错误: " + string(e.what()) + "\n";
		send(clientSocket, errMsg.c_str(), errMsg.size(), 0);
	}
}


//登录
void eComSys::logIn(SOCKET clientSocket) {
	auto sendPrompt = [clientSocket](const string& msg) {
		if (send(clientSocket, msg.c_str(), msg.size(), 0) == SOCKET_ERROR) {
			return;
		}
		};

	auto receiveInput = [clientSocket](char* buffer, int size) -> int {
		memset(buffer, 0, size);
		int bytes = recv(clientSocket, buffer, size - 1, 0); // 保留null终止符
		if (bytes > 0 && buffer[bytes - 1] == '\n') {
			buffer[bytes - 1] = '\0'; // 去除换行符
			bytes--;
		}
		return bytes;
		};

	try {
		char buffer[256];
		while (true) {
			// 发送用户名提示
			sendPrompt("\n请输入用户名（输入 q 返回主菜单）: ");

			// 接收用户名
			int idLen = receiveInput(buffer, sizeof(buffer));
			if (idLen <= 0) throw std::runtime_error("连接已断开");

			string id(buffer, idLen);
			if (id == "q") {
				sendPrompt("正在返回主菜单...\n");
				return;
			}

			// 发送密码提示
			sendPrompt("请输入密码: ");

			// 接收密码
			int pwdLen = receiveInput(buffer, sizeof(buffer));
			if (pwdLen <= 0) throw std::runtime_error("连接已断开");
			string pwd(buffer, pwdLen);

			// 验证用户
			auto it = users.find(id);
			if (it != users.end()) {
				if (it->second->checkPassword(pwd)) {
					currentUserID = id;
					string successMsg = "\n✅ 登录成功！用户类型: "
						+ it->second->getUserType() + "\n";
					sendPrompt(successMsg);

					// 进入对应菜单
					if (it->second->getUserType() == "consumer") {
						consumerMenu(clientSocket);
					}
					else {
						sellerMenu(clientSocket);
					}
					return;
				}
				else {
					sendPrompt("❌ 密码错误，请重试！\n");
				}
			}
			else {
				// 用户不存在处理
				sendPrompt("用户不存在，是否要注册？(y/n): ");

				int choiceLen = receiveInput(buffer, sizeof(buffer));
				if (choiceLen <= 0) throw std::runtime_error("连接已断开");

				if (tolower(buffer[0]) == 'y') {
					signIn(clientSocket);  // 调用注册流程
					sendPrompt("注册完成，请重新登录\n");
				}
				else {
					sendPrompt("取消注册，继续登录流程\n");
				}
			}
		}
	}
	catch (const std::runtime_error& e) {
		cerr << "登录异常: " << e.what() << endl;
		closesocket(clientSocket);
	}
	catch (...) {
		cerr << "未知登录错误" << endl;
		closesocket(clientSocket);
	}
}





//=================================================================================
// 菜单
//=================================================================================
//展现给消费者的菜单
void eComSys::consumerMenu(SOCKET clientSocket) {
	auto sendMenu = [this, clientSocket]() {
		const vector<string> items = {
			"修改密码", "查看余额", "充值", "查询密码",
			"浏览商品", "搜索商品", "添加商品到购物车",
			"查看/管理购物车", "生成订单", "管理订单", "返回主菜单"
		};

		ostringstream oss;
		oss << "\n" << createDivider() << "\n"
			<< centerText("消费者菜单") << "\n";

		for (size_t i = 0; i < items.size(); ++i) {
			oss << centerText(to_string(i + 1) + ". " + items[i]) << "\n";
		}

		oss << createDivider() << "\n"
			<< "请选择操作序号（1-" << items.size() << "）: ";

		if (send(clientSocket, oss.str().c_str(), oss.str().size(), 0) == SOCKET_ERROR) {
			throw std::runtime_error("菜单发送失败");
		}
		};

	auto receiveChoice = [clientSocket]() -> int {
		char buffer[16] = { 0 };
		int bytes = recv(clientSocket, buffer, sizeof(buffer) - 1, 0);
		if (bytes <= 0) return -1;
		return atoi(buffer);
		};

	auto receiveInput = [clientSocket]() -> string {
		char buffer[256] = { 0 };
		memset(buffer, 0, sizeof(buffer));
		int bytes = recv(clientSocket, buffer, sizeof(buffer)-1, 0); // 保留null终止符
		if (bytes > 0 && buffer[bytes - 1] == '\n') {
			buffer[bytes - 1] = '\0'; // 去除换行符
			bytes--;
		}
		return string(buffer);
		};

	auto validateNumber = [&](const string& input, double min, double max, double& outValue) -> bool {
		try {
			float value = stof(input);
			if (value >= min && value <= max) {
				outValue = value;
				return true;
			}
		}
		catch (...) {
			return false;
		}
		return false;
		};

	try {
		auto& currentUser = dynamic_cast<consumer&>(*users[currentUserID]);

		while (true) {
			sendMenu();
			int choice = receiveChoice();
			if (choice == -1) throw std::runtime_error("连接中断");

			ostringstream response;
			switch (choice) {
			case 1: { // 修改密码
				auto changePassword = [&]() {
					// 获取旧密码
					send(clientSocket, "请输入当前密码: ", 15, 0);
					char oldPwd[64] = { 0 };
					recv(clientSocket, oldPwd, sizeof(oldPwd) - 1, 0);

					if (!currentUser.checkPassword(oldPwd)) {
						send(clientSocket, "密码错误！\n", 10, 0);
						return false;
					}

					// 获取新密码
					auto getNewPwd = [&]() {
						send(clientSocket, "新密码要求：6-18位字母数字组合\n请输入新密码: ", 46, 0);
						char newPwd[64] = { 0 };
						recv(clientSocket, newPwd, sizeof(newPwd) - 1, 0);
						return string(newPwd);
						};

					string newPwd;
					while (true) {
						newPwd = getNewPwd();
						if (newPwd.length() < 6 || newPwd.length() > 18) {
							send(clientSocket, "密码不符合要求，请重新输入\n", 27, 0);
						}
						else {
							break;
						}
					}

					// 确认密码
					send(clientSocket, "请再次输入新密码: ", 18, 0);
					char confirm[64] = { 0 };
					recv(clientSocket, confirm, sizeof(confirm) - 1, 0);

					if (newPwd != confirm) {
						send(clientSocket, "两次输入不一致！\n", 14, 0);
						return false;
					}

					currentUser.setPassword(newPwd);
					userManager.saveAllUsers();
					return true;
					};

				if (changePassword()) {
					response << "密码修改成功！\n";
				}
				break;
			}

			case 2: { // 查看余额
				response << "当前余额: " << fixed << setprecision(2)
					<< currentUser.getAccountMoney() << "元\n";
				break;
			}

			case 3: { // 充值
				auto getAmount = [&]() -> double {
					double value;
					while (true) {
						send(clientSocket, "请输入充值金额（正数）: ", 25, 0);
						string input = receiveInput();
						if (validateNumber(input, 0.01, 1000000.0, value)) break;
						send(clientSocket, "输入无效，请重新输入\n", 25, 0);
					}
					return value;
					};

				double amount = getAmount();
				currentUser.recharge(amount);
				userManager.saveAllUsers();
				response << "充值成功！当前余额: "
					<< currentUser.getAccountMoney() << "元\n";
				break;
			}

			case 4:  // 查询密码
				response << "当前密码（安全提示）：" << currentUser.getPsw() << "\n";
				break;

			case 5:  // 浏览商品
				displayProducts(clientSocket);
				break;

			case 6:  // 搜索商品
				searchProducts(clientSocket);
				break;

			case 7: { // 添加购物车
				auto getInput = [&](const string& prompt) -> string {
					send(clientSocket, prompt.c_str(), prompt.size(), 0);
					char buffer[256] = { 0 };
					recv(clientSocket, buffer, sizeof(buffer) - 1, 0);
					return string(buffer);
					};

				string owner = getInput("请输入商品所有者: ");
				string productID = getInput("请输入商品ID: ");

				int quantity;
				while (true) {
					send(clientSocket, "请输入购买数量: ", 18, 0);
					string input = receiveInput();
					double value;
					if (validateNumber(input, 1, 9999, value) &&
						value == static_cast<int>(value)) {
						quantity = static_cast<int>(value);
						break;
					}
					send(clientSocket, "无效数量，请重新输入\n", 25, 0);
				}

				ProductKey key = { owner, productID };
				if (!products.count(key)) {
					response << "商品不存在！\n";
					break;
				}

				auto& cart = userCarts[currentUserID];
				cart.setConsumer(&currentUser);
				cart.addItem(key, quantity);
				response << "成功添加 " << quantity << " 件商品到购物车\n";
				break;
			}

			case 8: { // 管理购物车
				auto& cart = userCarts[currentUserID];
				auto items = cart.getItems();

				if (items.empty()) {
					response << "购物车为空！\n";
					break;
				}

				ostringstream cartOss;
				cartOss << "\n=== 购物车内容 ===\n";
				int index = 1;
				map<int, ProductKey> itemMap;
				double total = 0.0;

				for (auto& [key, qty] : items) {
					product* p = products[key].get();
					if (p) {
						double price = p->getPrice();
						cartOss << index << ". " << p->getDescription()
							<< " ×" << qty
							<< " 小计: " << (price * qty) << "元\n";
						total += price * qty;
						itemMap[index++] = key;
					}
				}
				cartOss << "总计: " << total << "元\n"
					<< "1.修改数量 2.删除商品 3.返回\n请选择操作: ";

				send(clientSocket, cartOss.str().c_str(), cartOss.str().size(), 0);

				int action = receiveChoice();
				if (action == 1) {
					send(clientSocket, "输入要修改的商品序号: ", 30, 0);
					int itemNum = receiveChoice();

					if (itemMap.count(itemNum)) {
						send(clientSocket, "输入新数量: ", 18, 0);
						int newQty = receiveChoice();

						if (newQty > 0) {
							cart.updateQuantity(itemMap[itemNum], newQty);
							response << "数量已修改\n";
						}
						else {
							response << "数量无效\n";
						}
					}
				}
				else if (action == 2) {
					send(clientSocket, "输入要删除的商品序号: ", 30, 0);
					int itemNum = receiveChoice();

					if (itemMap.count(itemNum)) {
						cart.removeItem(itemMap[itemNum]);
						response << "商品已移除\n";
					}
				}
				break;
			}

			case 9: { // 生成订单
				auto& cart = userCarts[currentUserID];
				if (cart.getItems().empty()) {
					response << "购物车为空！\n";
					break;
				}

				try {
					Order newOrder;
					newOrder.generateOrder(cart);
					cart.clear();
					orderManager.saveAllOrders();
					response << "订单生成成功！系统订单号: "
						<< newOrder.getOrderId() << "\n";
				}
				catch (const exception& e) {
					response << "错误: " << e.what() << "\n";
				}
				break;
			}

			case 10: { // 管理订单
				vector<Order*> userOrders;
				for (const auto& [id, order] : allOrders) {
					if (order->getConsumer() == &currentUser) {
						userOrders.push_back(order.get());
					}
				}

				if (userOrders.empty()) {
					response << "暂无订单！\n";
					break;
				}

				ostringstream orderOss;
				orderOss << "\n=== 我的订单，按序： ===\n";
				for (size_t i = 0; i < userOrders.size(); ++i) {
					Order* o = userOrders[i];
					orderOss << i+1 << ". "
						<< " [" << o->getStatusString() << "] "
						<< "总额: " << o->calculateTotal() << "元 "
						<< o->getConsumer()->getId() << "\n";
				}
				orderOss << "输入订单编号（0返回）: ";

				send(clientSocket, orderOss.str().c_str(), orderOss.str().size(), 0);

				int orderChoice = receiveChoice();
				if (orderChoice > 0 && orderChoice <= userOrders.size()) {
					Order* selected = userOrders[orderChoice - 1];

					send(clientSocket, "1.支付 2.取消 3.返回\n请选择操作: ", 30, 0);
					int action = receiveChoice();

					if (action == 1) {
						if (selected->payOrder()) {
							orderManager.saveAllOrders();
							response << "支付成功！\n";
						}
						else {
							response << "支付失败（余额不足）！\n";
						}
					}
					else if (action == 2) {
						selected->cancelOrder();
						orderManager.saveAllOrders();
						response << "订单已取消！\n";
						}
					}
				}
				break;
			case 11: // 返回主菜单
				return;

			default:
				response << "无效选项！\n";
			}
			if (!response.str().empty()) {
				send(clientSocket, response.str().c_str(), response.str().size(), 0);
			}
		}
		}
	catch (const exception& e) {
		string msg = "消费者菜单错误: " + string(e.what()) + "\n";
		send(clientSocket, msg.c_str(), msg.size(), 0);
		closesocket(clientSocket);
	}
}



void eComSys::sellerMenu(SOCKET clientSocket) {
	auto sendMenu = [this, clientSocket]() {
		const vector<string> items = {
			"查看余额", "充值", "修改密码", "查询密码",
			"管理商品", "添加商品", "浏览商品", "搜索商品", "返回主菜单"
		};

		ostringstream oss;
		oss << "\n" << createDivider() << "\n"
			<< centerText("商户菜单") << "\n";

		for (size_t i = 0; i < items.size(); ++i) {
			oss << centerText(to_string(i + 1) + ". " + items[i]) << "\n";
		}

		oss << createDivider() << "\n"
			<< "请选择操作序号（1-" << items.size() << "）: ";

		if (send(clientSocket, oss.str().c_str(), oss.str().size(), 0) == SOCKET_ERROR) {
			throw std::runtime_error("菜单发送失败");
		}
		};

	auto receiveChoice = [clientSocket]() -> int {
		char buffer[16] = { 0 };
		int bytes = recv(clientSocket, buffer, sizeof(buffer) - 1, 0);
		if (bytes <= 0) return -1;
		return atoi(buffer);
		};

	try {
		auto& currentUser = dynamic_cast<seller&>(*users[currentUserID]);

		while (true) {
			// 发送菜单
			sendMenu();

			// 接收选择
			int choice = receiveChoice();
			if (choice == -1) throw std::runtime_error("菜单发送失败");

			ostringstream response;
			switch (choice) {
			case 1: { // 查看余额
				response << "当前账户余额: " << fixed << setprecision(2)
					<< currentUser.getAccountMoney() << "元\n";
				break;
			}

			case 2: { // 充值
				auto getAmount = [&]() -> double {
					const string prompt = "请输入充值金额（正数）: ";
					send(clientSocket, prompt.c_str(), prompt.size(), 0);

					char buffer[32] = { 0 };
					recv(clientSocket, buffer, sizeof(buffer) - 1, 0);
					return stod(buffer);
					};

				double amount = getAmount();
				if (amount <= 0) {
					response << "金额必须大于0\n";
					break;
				}

				currentUser.recharge(amount);
				userManager.saveAllUsers();
				response << "充值成功！当前余额: "
					<< currentUser.getAccountMoney() << "元\n";
				break;
			}

			case 3: { // 修改密码
				auto changePassword = [&]() -> bool {
					// 获取旧密码
					send(clientSocket, "请输入当前密码: ", 15, 0);
					char oldPwd[64] = { 0 };
					recv(clientSocket, oldPwd, sizeof(oldPwd) - 1, 0);

					if (!currentUser.checkPassword(oldPwd)) {
						send(clientSocket, "密码错误！\n", 10, 0);
						return false;
					}

					// 获取新密码
					auto getNewPwd = [&]() {
						send(clientSocket, "新密码要求：6-18位字母数字组合\n请输入新密码: ", 46, 0);
						char newPwd[64] = { 0 };
						recv(clientSocket, newPwd, sizeof(newPwd) - 1, 0);
						return string(newPwd);
						};

					string newPwd;
					while (true) {
						newPwd = getNewPwd();
						if (newPwd.length() < 6 || newPwd.length() > 18) {
							send(clientSocket, "密码不符合要求，请重新输入\n", 27, 0);
						}
						else {
							break;
						}
					}

					// 确认密码
					send(clientSocket, "请再次输入新密码: ", 18, 0);
					char confirm[64] = { 0 };
					recv(clientSocket, confirm, sizeof(confirm) - 1, 0);

					if (newPwd != confirm) {
						send(clientSocket, "两次输入不一致！\n", 14, 0);
						return false;
					}

					currentUser.setPassword(newPwd);
					userManager.saveAllUsers();
					return true;
					};

				if (changePassword()) {
					response << "密码修改成功！\n";
				}
				break;
			}

			case 4:  // 查询密码（安全警告）
				response << "当前密码（安全提示：请勿泄露）: "
					<< currentUser.getPsw() << "\n";
				break;

			case 5:  // 商品管理
				manageProducts(clientSocket);
				break;

			case 6:  // 添加商品
				addProduct(clientSocket);
				break;

			case 7:  // 浏览商品
				displayProducts(clientSocket);
				break;

			case 8:  // 搜索商品
				searchProducts(clientSocket);
				break;

			case 9:  // 返回主菜单
				send(clientSocket, "正在返回主菜单\n", 19, 0);
				return;

			default:
				response << "无效选项，请重新选择\n";
				break;
			}

			// 发送操作结果
			if (!response.str().empty()) {
				send(clientSocket, response.str().c_str(), response.str().size(), 0);
			}
		}
	}
	catch (const exception& e) {
		string msg = "商户菜单错误: " + string(e.what()) + "\n";
		send(clientSocket, msg.c_str(), msg.size(), 0);
		closesocket(clientSocket);
	}
}



	// 显示完整菜单
void eComSys::MainMenu(SOCKET clientSocket) {
	// 发送菜单的lambda表达式
	auto sendMenu = [&]() {
		//cout << "主菜单1" << endl;
		std::stringstream menuStream;
		//cout << "主菜单2" << endl;
		// 构建菜单内容
		menuStream << "\n       😍请选择操作序号！";
		//cout << "主菜单2.5" << endl;
		if (!mainitems.empty()) {
			menuStream << "(1~" << mainitems.size() << ")";
		}
		//cout << "主菜单2.6" << endl;
		menuStream << "\n" << createDivider() << "\n"
			<< centerText("") << "\n";  // 顶部留空
		//cout << "主菜单3" << endl;
		for (size_t i = 0; i < mainitems.size(); ++i) {
			menuStream << centerText(to_string(i + 1) + "." + mainitems[i]) << "\n";
		}
		//cout << "主菜单4" << endl;
		menuStream << centerText("") << "\n"  // 底部留空
			<< createDivider() << "\n";
		// 发送完整菜单
		std::string menuStr = menuStream.str();
		send(clientSocket, menuStr.c_str(), menuStr.size(), 0);
		};

	// 初始化菜单选项（只需一次）
	if (!if_init) {
		addMainItem("退出");
		addMainItem("登录");
		addMainItem("注册");
		addMainItem("查看所有账号信息");
		addMainItem("展示商品");
		addMainItem("搜索商品");
		if_init = 1;
	}
	//cout << "主菜单1" << endl;
	// 主循环
	while (true) {
		//cout << "主菜单2" << endl;
		// 发送菜单到客户端
		sendMenu();

		// 接收客户端选择
		char buffer[1024];
		memset(buffer, 0, sizeof(buffer));
		int bytesReceived = recv(clientSocket, buffer, sizeof(buffer), 0);

		// 处理断开连接
		if (bytesReceived <= 0) {
			std::cerr << "客户端断开连接\n";
			break;
		}

		// 转换输入为整数
		int choice;
		try {
			choice = stoi(string(buffer, bytesReceived));
		}
		catch (...) {
			std::string errMsg = "输入无效，请重新输入数字！\n";
			send(clientSocket, errMsg.c_str(), errMsg.size(), 0);
			continue;
		}

		// 处理选项
		std::string response;
		bool validChoice = false;
		switch (choice) {
		case SYSQUIT: {
			std::string quitMsg = "正在退出系统...\n";
			send(clientSocket, quitMsg.c_str(), quitMsg.size(), 0);
			closesocket(clientSocket);
			return;  // 直接返回结束线程
		}
		case SYSLOGIN:
			logIn(clientSocket);  // 新增登录处理方法
			validChoice = true;
			break;
		case SYSSIGNIN:
			signIn(clientSocket); // 新增注册处理方法
			validChoice = true;
			break;
		case SYSCHECKALL:
			try {
				displayAllAc(clientSocket);
			}
			catch (const exception& e) {
				response = "显示账户异常: ";
			}
			validChoice = true;
			break;
		case 5:              //-----------------------------------<一定要隐藏每个选项具体的值
			displayProducts(clientSocket);
			validChoice = true;
			break;
		case 6:
			searchProducts(clientSocket);
			validChoice = true;
			break;
		default:
			response = "无效选项，请重新选择！\n";
			break;
		}

		// 发送响应
		if (!response.empty()) {
			send(clientSocket, response.c_str(), response.size(), 0);
		}



		// 保存数据（需要线程同步）
		// 暂时不需要互斥锁
		//std::lock_guard<std::mutex> lock(dataMutex);
		try {
			userManager.saveAllUsers();
			productManager.saveAllProducts();
		}
		catch (const exception& e) {
			std::string errMsg = "系统错误：数据保存失败\n";
			send(clientSocket, errMsg.c_str(), errMsg.size(), 0);
		}
	}
	closesocket(clientSocket);
}